# import jusmargui
from PySide2.QtWidgets import (
    QApplication,
    QWidget,
    QTableWidgetItem,
    QTableWidget,
    QHeaderView,
    QAbstractItemView,
    QVBoxLayout,
    QTabWidget,
    QGroupBox,
    QLabel,
    QLineEdit,
    QHBoxLayout,
    QGridLayout,
    QComboBox,
    QPushButton,
    QListWidget,
    QDialog,
    QButtonGroup,
    QRadioButton,
    QCheckBox,
    QListWidgetItem,
    QMessageBox,
    QGraphicsColorizeEffect,
    QFileDialog,
    QSpacerItem,
)
from PySide2.QtCore import Qt, Signal
from PySide2.QtGui import QPixmap, QDoubleValidator, QIntValidator, QImage
import sys
import csv
import os
import json
import subprocess
import re
from gui.controls import envs
from .. import config as Config
from ..utils import Utils
from ..dlg_model_params import DlgModeResetCls
from ..params_table import ParamsTable, OnlyOneRowTable
from ..custom_widget import SelectSearchBox, LineEditInt, MultRadioBtnGroup, SelectBox
from ..util.parameter_mapping import (
    SectionConnectionMap,
    SectionConnectionReverseMap,
    typeSectionMap,
    typeSectionReverseMap,
)
from ..util.library_json import getStringedBarLibrary
from .. import message_box as MBox
from ..util.utils_empty import var_is_empty


class DlgSectionConnection(DlgModeResetCls):
    sectionConnection_save_signal = Signal(object)

    def __init__(self, parent=None, params={}):
        super().__init__(parent)
        self.setWindowTitle("舱段连接")
        self.resize(400, 450)

        # 解析数据
        self.connects = params.get("connects") or {}
        self.data = params.get("data") or {}
        self.info = self.parseContects(self.connects)

        layoutWrap = QHBoxLayout()
        layout = QVBoxLayout()
        layoutWrap.addStretch(1)
        layoutWrap.addLayout(layout)
        layoutWrap.addStretch(1)

        self.widgetDict = {}
        self.isLoad = False

        self.section1GroupBox = QGroupBox()
        section1Layout = QVBoxLayout()
        section1LayoutWrap = QHBoxLayout()
        section1LayoutWrap.addStretch(1)
        section1LayoutWrap.addLayout(section1Layout)
        section1LayoutWrap.addStretch(1)
        self.section1GroupBox.setLayout(section1LayoutWrap)
        self.widgetDict["part1Id"] = SelectSearchBox(
            options=[],
            onChanged=lambda *args, **kwargs: self.part1IdChanged(
                self, *args, **kwargs
            ),
        )
        self.widgetDict["part2Id"] = SelectSearchBox(
            options=[],
            onChanged=lambda *args, **kwargs: self.part2IdChanged(
                self, *args, **kwargs
            ),
        )
        self.widgetDict["section1Value"] = SelectSearchBox(options=[])

        self.widgetDict["section1"] = SelectBox(
            options=[
                {"title": "点", "value": "点"},
                {"title": "面", "value": "面"},
                {"title": "自由", "value": "自由"},
            ],
            onChanged=lambda *args, **kwargs: self.section1Changed(
                self, *args, **kwargs
            ),
        )

        self.widgetDict["part1Id"].setFixedWidth(150)
        section1Layout.addWidget(self.widgetDict["part1Id"])

        self.widgetDict["section1"].setFixedWidth(150)
        self.widgetDict["section1Value"].setFixedWidth(150)
        section1Layout.addWidget(self.widgetDict["section1"])
        section1Layout.addWidget(self.widgetDict["section1Value"])

        self.section2GroupBox = QGroupBox()
        section2LayoutWrap = QHBoxLayout()
        section2Layout = QVBoxLayout()
        section2LayoutWrap.addStretch(1)
        section2LayoutWrap.addLayout(section2Layout)
        section2LayoutWrap.addStretch(1)
        self.section2GroupBox.setLayout(section2LayoutWrap)

        self.widgetDict["part2Id"].setFixedWidth(150)
        section2Layout.addWidget(self.widgetDict["part2Id"])

        self.widgetDict["section2"] = SelectBox(
            options=[
                {"title": "点", "value": "点"},
                {"title": "面", "value": "面"},
                {"title": "自由", "value": "自由"},
            ],
            onChanged=lambda *args, **kwargs: self.section2Changed(
                self, *args, **kwargs
            ),
        )
        self.widgetDict["section2"].setFixedWidth(150)
        section2Layout.addWidget(self.widgetDict["section2"])

        self.widgetDict["section2Value"] = SelectSearchBox(options=[])
        self.widgetDict["section2Value"].setFixedWidth(150)
        section2Layout.addWidget(self.widgetDict["section2Value"])

        icon = envs.qicons.qicon_add()
        addImg = QLabel()
        addImg.setAlignment(Qt.AlignCenter)
        pixmap = icon.pixmap(20, 20)
        addImg.setPixmap(pixmap)
        gridLayout = QGridLayout()
        gridLayout.addWidget(self.section1GroupBox, 0, 0)
        gridLayout.addWidget(addImg, 0, 1)
        gridLayout.addWidget(self.section2GroupBox, 0, 2)

        wrapLayout1 = QHBoxLayout()
        wrapLayout2 = QVBoxLayout()
        wrapLayout1.stretch(1)
        wrapLayout1.addLayout(wrapLayout2)
        wrapLayout1.stretch(1)

        self.connectionIdWidget = self.createContentNumWidget()
        connectionIdLayout = QHBoxLayout()
        wrapLayout2.addLayout(connectionIdLayout)
        connectionIdLayout.addWidget(self.connectionIdWidget)
        connectionIdLayout.addStretch(1)

        wrapLayout2.addLayout(gridLayout)
        layout.addLayout(wrapLayout1)

        self.tempLayout = QHBoxLayout()
        self.surfaceWidget = self.createSurfaceWidget()
        self.con_height = self.createCon_heightWidget()
        self.freeWidget = self.createFreeWidget()
        self.surfaceWidget.setVisible(False)
        self.con_height.setVisible(False)
        self.freeWidget.setVisible(False)

        self.tempLayout.addWidget(self.surfaceWidget)
        self.tempLayout.addWidget(self.con_height)
        layout.addLayout(self.tempLayout)
        layout.addWidget(self.freeWidget)

        layout.addStretch(1)

        btnLayout = QHBoxLayout()
        cancelBtn = QPushButton("取消")
        okBtn = QPushButton("确定")

        btnLayout.setAlignment(Qt.AlignCenter)
        btnLayout.addWidget(okBtn)
        btnLayout.addWidget(cancelBtn)
        layout.addLayout(btnLayout)

        okBtn.clicked.connect(self.on_okBtn_clicked)
        cancelBtn.clicked.connect(self.close)

        self.setLayout(layoutWrap)

        self.isLoad = True
        self.widgetDict["part1Id"].updateItem(self.info["types"])
        self.widgetDict["part1Id"].setValue(
            self.connects["connectsTitles"][0].get("title")
        )
        self.widgetDict["part2Id"].updateItem(self.info["types"])
        self.widgetDict["part2Id"].setValue(
            self.connects["connectsTitles"][1].get("title")
        )
        self.updateUI(self.data)

    def parseContects(self, contects):
        optionsDict = {}
        section2Types = {}

        types1 = []
        sections = contects.get("sections") or []
        idToName = {}
        nameToId = {}
        for i, item in enumerate(sections):
            id = item.get("ID")
            sectionName = item.get("sectionName")
            data = item.get("data") or {}
            type = data.get("type")
            types1.append(sectionName)
            ids = self.getIds(type=type, data=data)
            idToName[id] = sectionName
            nameToId[sectionName] = id
            optionsDict[sectionName] = ids
            section2Types[sectionName] = type

        converted_dict = Utils.convertedSortAndFormat(optionsDict)
        dataDict = {
            "types": types1,
        }
        converted_dataDict = {
            key: [
                {"title": item, "value": item} if item is not None else None
                for item in value
            ]
            for key, value in dataDict.items()
        }
        converted_dataDict["options"] = converted_dict
        converted_dataDict["section2Types"] = section2Types
        converted_dataDict["nameToId"] = nameToId
        converted_dataDict["idToName"] = idToName

        return converted_dataDict

    def getIds(self, type, data={}):
        ids = []
        if data:
            if type == "shell_bar":
                ringFrameData = (data.get("grid_set") or [[]]) + (
                    data.get("grid_ring") or [[]]
                )
                for item in ringFrameData:
                    if len(item) > 0:
                        ids.append(item[0])
            elif type == "bar_3d":
                if data.get("grid"):
                    if len(data.get("grid")) > 0 and len(data["grid"][0]) > 0:
                        ids.append(data["grid"][0][0])
                    if len(data.get("grid")) > 1 and len(data["grid"][1]) > 0:
                        ids.append(data["grid"][1][0])
            elif type == "point_mass":
                ids.append(data.get("grid_id"))
            elif type == "bar_conm":
                grid = data.get("grid") or []
                for item in grid:
                    if item and isinstance(item, list) and len(item) > 0:
                        ids.append(item[0])

        ids = [item for item in ids if item is not None]
        return ids

    def getStageOptionData(self, select, index):
        options = []
        data = {}
        ls = (self.connects[index].get("data") or {}).get("sections") or []
        if select == "点":
            # 梁与质量点建模
            for item in ls:
                if item.get("type") == "梁与质量点建模":
                    itemDict = item.get("data") or {}
                    data = data + (itemDict.get("grid") or {})
        elif select == "面":
            # 梁与质量点建模
            for item in ls:
                if item.get("type") == "蒙皮桁条建模":
                    itemDict = item.get("data") or {}
                    data = data + (itemDict.get("ringFrame") or {})
                if item.get("type") == "杆系建模":
                    itemDict = item.get("data") or {}
                    data = (
                        data
                        + (itemDict.get("topSurface") or {})
                        + (itemDict.get("bottomSurface") or {})
                    )
        if data:
            for key, _ in data.items():
                options.append({"title": key, "value": key})
        return options

    def createSurfaceWidget(self):
        surfaceGroupBox = QGroupBox("Group")
        surfaceLayout = QVBoxLayout()

        self.widgetDict["allAround"] = MultRadioBtnGroup(
            options=[{"title": "周向全选", "value": "周向全选"}],
            onChanged=lambda *args, **kwargs: self.selectAllChanged(*args, **kwargs),
        )
        surfaceLayout.addWidget(self.widgetDict["allAround"])
        self.widgetDict["surfaceTable"] = ParamsTable(rows=0, columns=2)
        self.widgetDict["surfaceTable"].setHorizontalHeaderLabels(
            [
                "约束角度",
                "约束范围",
            ]
        )
        self.widgetDict["surfaceTable"].rowSetFloat([0, 1])
        surfaceLayout.addWidget(self.widgetDict["surfaceTable"])
        surfaceGroupBox.setLayout(surfaceLayout)
        return surfaceGroupBox

    def createCon_heightWidget(self):
        con_heightGroupBox = QGroupBox("con_height")
        con_heightLayout = QVBoxLayout()

        self.widgetDict["con_height"] = OnlyOneRowTable(
            rows=0, columns=2, isNoAddAndDel=True
        )
        self.widgetDict["con_height"].setHorizontalHeaderLabels(
            ["起始高度", "终止高度"]
        )
        self.widgetDict["con_height"].rowSetFloat([0, 1])
        self.widgetDict["con_height"].addRow()
        con_heightLayout.addWidget(self.widgetDict["con_height"])
        con_heightGroupBox.setLayout(con_heightLayout)
        return con_heightGroupBox

    def createFreeWidget(self):
        self.widgetDict["freeTable"] = OnlyOneRowTable(
            rows=0, columns=2, isNoAddAndDel=True
        )
        self.widgetDict["freeTable"].setHorizontalHeaderLabels(
            [
                "主节点",
                "从节点",
            ]
        )
        self.widgetDict["freeTable"].rowSetInt([0])
        self.widgetDict["freeTable"].addRow()
        return self.widgetDict["freeTable"]

    def createContentNumWidget(self):
        connectionIdWidget = QWidget()
        connectionIdWidget.setFixedWidth(240)
        connectionIdLayout = QGridLayout()
        label1 = QLabel("连接的自由度")
        self.widgetDict["connectionId"] = LineEditInt()
        self.widgetDict["connectionId"].setValue(123456)
        self.widgetDict["connectionId"].setClearButtonEnabled(False)
        connectionIdLayout.addWidget(label1, 0, 0)
        connectionIdLayout.addWidget(self.widgetDict["connectionId"], 0, 1)

        label2 = QLabel("id")
        self.widgetDict["id"] = LineEditInt()
        self.widgetDict["id"].setClearButtonEnabled(False)
        connectionIdLayout.addWidget(label2, 1, 0)
        connectionIdLayout.addWidget(self.widgetDict["id"], 1, 1)

        connectionIdWidget.setLayout(connectionIdLayout)
        return connectionIdWidget
    
    def selectAllChanged(self, *args, **kwargs):
        value = self.widgetDict["allAround"].getValue()
        if value and len(value) >= 1:
            self.widgetDict["surfaceTable"].setEnabled(False)
        else:
            self.widgetDict["surfaceTable"].setEnabled(True)

    def on_okBtn_clicked(self):
        dict = {}
        for key, widget in self.widgetDict.items():
            if key == "id":
                idValue = widget.getValue()
                if var_is_empty(idValue):
                    MBox.warning("id不可为空!")
                    return
            if widget.isVisible() and widget.isEnabled():
                if key == "part1Id" or key == "part2Id":
                    nameToId = self.info.get("nameToId") or {}
                    dict[SectionConnectionMap[key]] = nameToId.get(widget.getValue())
                    continue
                if key == "allAround":
                    if len(widget.getValue()) >= 1:
                        dict[SectionConnectionMap[key]] = True
                    else:
                        dict[SectionConnectionMap[key]] = False

                elif isinstance(widget, QTableWidget):
                    temp = widget.getTableData()
                    if key == "freeTable" or key == "con_height":
                        if temp and len(temp) >= 1:
                            dict[SectionConnectionMap[key]] = temp[0]
                    else:
                        dict[SectionConnectionMap[key]] = temp
                else:
                    if key == "section1" or key == "section2":
                        continue
                    dict[SectionConnectionMap[key]] = widget.getValue()

        dict["type"] = (
            str(typeSectionMap.get(self.widgetDict["section1"].getValue()))
            + "2"
            + str(typeSectionMap.get(self.widgetDict["section2"].getValue()))
        )

        dict = Utils.filter_dict_list(dict)
        dict = Utils.filterDictEmptyProperty(dict)
        self.cacheFile = Config.cachePath + "test11121.json"
        Utils.write_json(self.cacheFile, dict)
        self.close()
        self.sectionConnection_save_signal.emit(dict)

    def updateUI(self, data):
        if data:
            for key, value in data.items():
                widget = SectionConnectionReverseMap.get(key)
                if widget in self.widgetDict:
                    if widget == "part1Id" or widget == "part2Id":
                        idToName = self.info.get("idToName") or {}
                        self.widgetDict[widget].setValue(idToName.get(value))

                    elif widget == "allAround":
                        if value:
                            self.widgetDict[widget].setValue(["周向全选"])
                    elif isinstance(self.widgetDict[widget], QTableWidget):
                        if widget == "freeTable" or widget == "con_height":
                            if value:
                                temp = [value]
                        else:
                            temp = value
                        for rowData in temp:
                            if widget == "con_height" or widget == "freeTable":
                                self.widgetDict[widget].fillRowData(
                                    row=0, rowData=rowData
                                )
                            else:
                                self.widgetDict[widget].addRow(rowData=rowData)
                    elif isinstance(self.widgetDict[widget], QComboBox):
                        if widget == "section1" or widget == "section2":
                            continue
                        self.widgetDict[widget].setValue(str(value))
                    else:
                        if widget == "section1" or widget == "section2":
                            continue
                        self.widgetDict[widget].setValue(value)

            type = data.get("type")
            if type and "2" in type:
                parts = re.split(r"2", type)  # 使用数字作为分隔符分割字符串
                self.widgetDict["section1"].setValue(
                    typeSectionReverseMap.get(parts[0])
                )
                self.widgetDict["section2"].setValue(
                    typeSectionReverseMap.get(parts[-1])
                )

        self.widgetDict["section1Value"].setValue(Utils.toInt(data.get("con_id1")))
        self.widgetDict["section2Value"].setValue(Utils.toInt(data.get("con_id2")))

    def part1IdChanged(self, *args):

        self.widgetDict["section1Value"].updateItem(self.info["options"].get(args[1]))
        types = self.info.get("section2Types") or {}
        self.setStageOptions(
            options=(types.get(args[1])), select=self.widgetDict["section1"]
        )

    def part2IdChanged(self, *args):
        self.widgetDict["section2Value"].updateItem(self.info["options"].get(args[1]))
        types = self.info.get("section2Types") or {}
        section1Value = self.widgetDict["section1"].getValue() or ""
        self.setStageOptions(
            options=(types.get(args[1])),
            select=self.widgetDict["section2"],
            previous=section1Value,
            isFree=False,
        )

    def setSectionOptions(self, flagList, select, previous=""):
        if "梁与质量点建模" in flagList or "集中质量建模" in flagList:
            if previous == "点":
                select.updateItem([{"title": "点", "value": "点"}])
            elif previous == "面":
                select.updateItem([])
            elif previous == "自由":
                select.updateItem([{"title": "自由", "value": "自由"}])
            else:
                select.updateItem(
                    [{"title": "点", "value": "点"}, {"title": "自由", "value": "自由"}]
                )
        elif "蒙皮桁条建模" in flagList or "杆系建模" in flagList:
            if previous == "点":
                select.updateItem([{"title": "面", "value": "面"}])
            elif previous == "面":
                select.updateItem([{"title": "面", "value": "面"}])
            elif previous == "自由":
                select.updateItem([{"title": "自由", "value": "自由"}])
            else:
                select.updateItem(
                    [{"title": "面", "value": "面"}, {"title": "自由", "value": "自由"}]
                )
        elif "导入bdf" in flagList:
            select.updateItem([{"title": "自由", "value": "自由"}])
            if previous == "点":
                select.updateItem([])
            elif previous == "面":
                select.updateItem([])
            elif previous == "自由":
                select.updateItem([{"title": "自由", "value": "自由"}])
            else:
                select.updateItem([{"title": "自由", "value": "自由"}])
        else:
            select.updateItem([])

    def section1Changed(self, *args):
        part2Value = self.widgetDict["part2Id"].getValue()
        section1Value = self.widgetDict["section1"].getValue() or ""
        types = self.info.get("section2Types") or {}
        if args[1] == "点":
            self.widgetDict["section1Value"].setVisible(True)
            self.widgetDict["section2Value"].setVisible(True)
        if args[1] == "面":
            self.widgetDict["section1Value"].setVisible(True)
            self.widgetDict["section2Value"].setVisible(True)
        elif args[1] == "自由":
            self.widgetDict["section2"].updateItem([{"title": "自由", "value": "自由"}])
            self.widgetDict["section1Value"].setVisible(False)
            self.widgetDict["section2Value"].setVisible(False)

        self.setStageOptions(
            options=(types.get(part2Value)),
            select=self.widgetDict["section2"],
            previous=section1Value,
            isFree=False,
        )

        self.showTable()

    def section2Changed(self, *args):
        self.showTable()

    def showTable(self):
        if not self.isLoad:
            return
        if (
            self.widgetDict["section1"].getValue() == "面"
            or self.widgetDict["section2"].getValue() == "面"
        ):
            self.surfaceWidget.setVisible(True)
            self.freeWidget.setVisible(False)
        elif (
            self.widgetDict["section1"].getValue() == "自由"
            or self.widgetDict["section2"].getValue() == "自由"
        ):
            self.surfaceWidget.setVisible(False)
            self.freeWidget.setVisible(True)
        elif (
            self.widgetDict["section1"].getValue() == "点"
            and self.widgetDict["section2"].getValue() == "点"
        ):
            self.surfaceWidget.setVisible(False)
            self.freeWidget.setVisible(False)
        else:
            self.surfaceWidget.setVisible(False)
            self.freeWidget.setVisible(False)

        if (
            self.widgetDict["section1"].getValue() == "点"
            and self.widgetDict["section2"].getValue() == "面"
        ):

            self.con_height.setVisible(True)
        elif (
            self.widgetDict["section1"].getValue() == "面"
            and self.widgetDict["section2"].getValue() == "点"
        ):

            self.con_height.setVisible(True)
        else:
            self.con_height.setVisible(False)

    def setStageOptions(self, options, select, previous="", isFree=True):
        opt = []
        if "bar_conm" == options or "point_mass" == options:
            if previous == "点" or previous == "面" or previous == "":
                if {"title": "点", "value": "点"} not in opt:
                    opt.append({"title": "点", "value": "点"})
            if previous == "自由" or previous == "":
                if {"title": "自由", "value": "自由"} not in opt:
                    opt.append({"title": "自由", "value": "自由"})

        if "bar_3d" == options or "shell_bar" == options:
            if previous == "点" or previous == "面" or previous == "":
                if {"title": "面", "value": "面"} not in opt:
                    opt.append({"title": "面", "value": "面"})
            if previous == "自由" or previous == "":
                if {"title": "自由", "value": "自由"} not in opt:
                    opt.append({"title": "自由", "value": "自由"})

        if "bdf" == options:
            if previous == "自由" or previous == "":
                if {"title": "自由", "value": "自由"} not in opt:
                    opt.append({"title": "自由", "value": "自由"})

        if options and isFree:
            if {"title": "自由", "value": "自由"} not in opt:
                opt.append({"title": "自由", "value": "自由"})
        select.updateItem(opt)


# if __name__ == "__main__":
#     app = QApplication(sys.argv)
#     window = SectionConnectionDialog()
#     window.show()
#     sys.exit(app.exec_())
